import * as DomUtil from '../../dom/DomUtil';
import * as Util from '../../core/Util';
import { Renderer } from './Renderer';

/*
 * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
 */

export var vmlCreate = (function () {
  try {
    document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
    return function (name) {
      return document.createElement('<lvml:' + name + ' class="lvml">');
    };
  } catch (e) {
    // Do not return fn from catch block so `e` can be garbage collected
    // See https://github.com/Leaflet/Leaflet/pull/7279
  }
  return function (name) {
    return document.createElement(
      '<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">',
    );
  };
})();

/*
 * @class SVG
 *
 *
 * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility
 * with old versions of Internet Explorer.
 */

// mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences
export var vmlMixin = {
  _initContainer: function () {
    this._container = DomUtil.create('div', 'leaflet-vml-container');
  },

  _update: function () {
    if (this._map._animatingZoom) {
      return;
    }
    Renderer.prototype._update.call(this);
    this.fire('update');
  },

  _initPath: function (layer) {
    var container = (layer._container = vmlCreate('shape'));

    DomUtil.addClass(
      container,
      'leaflet-vml-shape ' + (this.options.className || ''),
    );

    container.coordsize = '1 1';

    layer._path = vmlCreate('path');
    container.appendChild(layer._path);

    this._updateStyle(layer);
    this._layers[Util.stamp(layer)] = layer;
  },

  _addPath: function (layer) {
    var container = layer._container;
    this._container.appendChild(container);

    if (layer.options.interactive) {
      layer.addInteractiveTarget(container);
    }
  },

  _removePath: function (layer) {
    var container = layer._container;
    DomUtil.remove(container);
    layer.removeInteractiveTarget(container);
    delete this._layers[Util.stamp(layer)];
  },

  _updateStyle: function (layer) {
    var stroke = layer._stroke,
      fill = layer._fill,
      options = layer.options,
      container = layer._container;

    container.stroked = !!options.stroke;
    container.filled = !!options.fill;

    if (options.stroke) {
      if (!stroke) {
        stroke = layer._stroke = vmlCreate('stroke');
      }
      container.appendChild(stroke);
      stroke.weight = options.weight + 'px';
      stroke.color = options.color;
      stroke.opacity = options.opacity;

      if (options.dashArray) {
        stroke.dashStyle = Util.isArray(options.dashArray)
          ? options.dashArray.join(' ')
          : options.dashArray.replace(/( *, *)/g, ' ');
      } else {
        stroke.dashStyle = '';
      }
      stroke.endcap = options.lineCap.replace('butt', 'flat');
      stroke.joinstyle = options.lineJoin;
    } else if (stroke) {
      container.removeChild(stroke);
      layer._stroke = null;
    }

    if (options.fill) {
      if (!fill) {
        fill = layer._fill = vmlCreate('fill');
      }
      container.appendChild(fill);
      fill.color = options.fillColor || options.color;
      fill.opacity = options.fillOpacity;
    } else if (fill) {
      container.removeChild(fill);
      layer._fill = null;
    }
  },

  _updateCircle: function (layer) {
    var p = layer._point.round(),
      r = Math.round(layer._radius),
      r2 = Math.round(layer._radiusY || r);

    this._setPath(
      layer,
      layer._empty()
        ? 'M0 0'
        : 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + 65535 * 360,
    );
  },

  _setPath: function (layer, path) {
    layer._path.v = path;
  },

  _bringToFront: function (layer) {
    DomUtil.toFront(layer._container);
  },

  _bringToBack: function (layer) {
    DomUtil.toBack(layer._container);
  },
};
